﻿using MQTTnet;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Options;
using MQTTnet.Client.Receiving;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Server;
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Text;
using System.Threading.Tasks;

namespace Zhaoxi.MQTTClient
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("欢迎使用朝夕教育MQTT客户端!");
            //Connect1();

            // 业务逻辑  订阅  发布
            Connect();

            Console.ReadLine();
        }

        static void Connect1()
        {
            // 连接到MQTT服务器
            IManagedMqttClient client = new MqttFactory().CreateManagedMqttClient();
            //client.ConnectedHandler
            //client.DisconnectedHandler
            client.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(Client_ApplicationMessageReceived);

            // IP   Port   Client ID
            // UserName  Password
            IMqttClientOptions clientOptions = new MqttClientOptionsBuilder()
                .WithClientId("ZX001")
                .WithTcpServer("127.0.0.1", 1883)
                .WithCredentials("admin", "123456")
                .Build();
            IManagedMqttClientOptions options = new ManagedMqttClientOptionsBuilder()
                .WithClientOptions(clientOptions)
                .Build();

            client.StartAsync(options);// 异步连接到服务器
        }
        static async void Connect()
        {
            // 连接到MQTT服务器
            IManagedMqttClient client = new MqttFactory().CreateManagedMqttClient();
            client.ConnectedHandler = new MqttClientConnectedHandlerDelegate(e =>
            {

            });
            client.ConnectingFailedHandler = new ClientConnectingFaildHandler(e =>
            {
            });
            //client.DisconnectedHandler
            client.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(Client_ApplicationMessageReceived);

            // IP   Port   Client ID
            // UserName  Password
            IMqttClientOptions clientOptions = new MqttClientOptionsBuilder()
                .WithClientId("ZX001")
                .WithTcpServer("127.0.0.1", 1883)
                .WithCredentials("admin", "34234")
                //.WithWillMessage(),
                .Build();
            IManagedMqttClientOptions options = new ManagedMqttClientOptionsBuilder()
                .WithClientOptions(clientOptions)
                .Build();

            await client.StartAsync(options);// 异步连接到服务器


            // 订阅主题过滤器
            MqttTopicFilter topicFilter = new MqttTopicFilterBuilder()
                .WithTopic("test")// 主题
                .WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce)
                .Build();
            await client.SubscribeAsync(topicFilter);
            //client.UnsubscribeAsync()


            await Task.Delay(1000);
            // 发布（）     TCP  点对点
            // 针对某个主题发布   需要指定主题 
            // 针对这个主题的内容（负载）
            string msg = "Hello Zhaoxi";
            MqttApplicationMessage message = new MqttApplicationMessageBuilder()
                .WithTopic("test")
                .WithPayload(Encoding.Default.GetBytes(msg))
                .WithRetainFlag(false)
                .Build();
            await client.PublishAsync(message);
        }

        // 响应订阅主题的消息
        static void Client_ApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            Console.WriteLine(">>> 收到消息:" + e.ApplicationMessage.ConvertPayloadToString() + ",来自客户端" + e.ClientId + ",主题:" + e.ApplicationMessage.Topic);
        }
    }

    class ClientConnectingFaildHandler : IConnectingFailedHandler
    {
        Action<ManagedProcessFailedEventArgs> action;

        public ClientConnectingFaildHandler(Action<ManagedProcessFailedEventArgs> a)
        {
            action = a;
        }
        public Task HandleConnectingFailedAsync(ManagedProcessFailedEventArgs eventArgs)
        {
            action(eventArgs);
            return Task.CompletedTask;
        }
    }
}
